#include "KeyboardManager.h"

namespace Lame3d
{
	KeyboardManager::KeyboardManager()
	{
	}
	
	KeyboardManager::~KeyboardManager()
	{
		std::map<std::string, KeyboardCallback*>::iterator it;
		for(it = callbacks.begin(); it != callbacks.end(); ++it) {
			delete it->second;
		}
	}
	
	void KeyboardManager::RegisterCallback(KeyboardCallback *kc) 
	{
		RegisterCallback(*kc);
	}
	
	void KeyboardManager::RegisterCallback(KeyboardCallback &kc)
	{
		std::map<std::string, KeyboardCallback*>::iterator it;
		it = callbacks.find(kc.Name());
		if(it != callbacks.end()) {
			throw "Attempted to register callback --- Name already taken!";
		} else {
			callbacks[kc.Name()] = &kc;
		}
	}
	
	void KeyboardManager::BindCallback(const KeyEvent &e, const std::string &callbackName)
	{
		std::map<std::string, KeyboardCallback*>::iterator it;
		it = callbacks.find(callbackName);
		if(it != callbacks.end()) {
			bindings[e] = it->second;
			//printf("Bound key %s to %s\n", e.String().c_str(), it->second->Name().c_str());
		} else {
			throw "Attempted to bind nonexistant callback to keyboard!";
		}
	}
	
	void KeyboardManager::UnbindCallback(const std::string &callback)
	{
		std::map<KeyEvent, KeyboardCallback*>::iterator it;
		std::list<KeyEvent> toErase;
		for(it = bindings.begin(); it != bindings.end(); ++it) {
			if(it->second->Name() == callback) {
				toErase.push_back(it->first);
			}
		}
		while(!toErase.empty()) {
			bindings.erase(toErase.front());
			toErase.pop_front();
		}
	}
	
	void KeyboardManager::UnbindKey(const KeyEvent &e)
	{
		bindings.erase(e);
	}
	
	std::map<KeyEvent, KeyboardCallback*>::const_iterator KeyboardManager::BindingsIterator() const
	{
		return bindings.begin();
	}
	
	std::map<std::string, KeyboardCallback*>::const_iterator KeyboardManager::CallbackIterator() const
	{
		return callbacks.begin();
	}
	
	void KeyboardManager::Handle(std::list<KeyEvent*> &events)
	{
		while(!events.empty()) {
			Handle(*events.front());
			delete events.front();
			events.pop_front();
		}
	}
	
	void KeyboardManager::Handle(KeyEvent &e)
	{
		//printf("Key event %s...\n", e.String().c_str());
		std::map<KeyEvent, KeyboardCallback*>::iterator it;
		it = bindings.find(e);
		if(it != bindings.end()) {
			it->second->KeyboardEvent(e);
		} else {
			//printf("Couldn't find handler.\n");
		}
	}
}

// eof //
